package com.hzy.fivepalace.wx.service;


import com.hzy.fivepalace.common.util.RegexUtils;
import com.hzy.fivepalace.common.util.ResponseUtil;
import com.hzy.fivepalace.db.domain.DtsAddress;
import com.hzy.fivepalace.db.domain.DtsRegion;
import com.hzy.fivepalace.db.service.DtsAddressService;
import com.hzy.fivepalace.db.service.DtsRegionService;
import com.hzy.fivepalace.wx.controller.base.BaseController;
import jodd.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 * 用户收货地址服务
 */
@Service
public class WxAddressService extends BaseController {
    private static final Logger logger = LoggerFactory.getLogger(WxAddressService.class);

    @Autowired
    private DtsAddressService addressService;

    @Autowired
    private DtsRegionService regionService;

    private final static ArrayBlockingQueue<Runnable> WORK_QUEUE = new ArrayBlockingQueue<>(6);

    private final static RejectedExecutionHandler HANDLER = new ThreadPoolExecutor.CallerRunsPolicy();

    private static ThreadPoolExecutor executorService = new ThreadPoolExecutor(3, 6, 1000, TimeUnit.MILLISECONDS,
            WORK_QUEUE, HANDLER);

    /**
     * 用户收货地址列表
     * @param userId
     * @param queryType
     * @return
     */
    public Object list(Integer userId,Integer queryType) {
        List<DtsAddress> addressList = addressService.queryByUid(userId,queryType);
        List<DtsAddress> addressListNew = new ArrayList<>();
        //排序，默认地址设置到第一个，其他按时间排序
        addressList.forEach(item -> {
            if (item.getIsDefault()) {
                addressListNew.add(item);
            }
        });
        //这里取非默认的
        addressList.forEach(item -> {
            if (!item.getIsDefault()) {
                addressListNew.add(item);
            }
        });

        List<Map<String, Object>> addressVoList = new ArrayList<>(addressListNew.size());
        List<DtsRegion> regionList = getDtsRegions();
        for (DtsAddress address : addressListNew) {
            Map<String, Object> addressVo = new HashMap<>();
            addressVo.put("id", address.getId());
            addressVo.put("name", address.getName());
            addressVo.put("mobile", address.getMobile());
            addressVo.put("isDefault", address.getIsDefault());
            Callable<String> provinceCallable = () -> regionList.stream()
                    .filter(region -> region.getId().equals(address.getProvinceId())).findAny().orElse(null).getName();
            Callable<String> cityCallable = () -> regionList.stream()
                    .filter(region -> region.getId().equals(address.getCityId())).findAny().orElse(null).getName();
            Callable<String> areaCallable = () -> regionList.stream()
                    .filter(region -> region.getId().equals(address.getAreaId())).findAny().orElse(null).getName();
            FutureTask<String> provinceNameCallableTask = new FutureTask<>(provinceCallable);
            FutureTask<String> cityNameCallableTask = new FutureTask<>(cityCallable);
            FutureTask<String> areaNameCallableTask = new FutureTask<>(areaCallable);
            executorService.submit(provinceNameCallableTask);
            executorService.submit(cityNameCallableTask);
            executorService.submit(areaNameCallableTask);
            String detailedAddress = "";
            try {
                String province = provinceNameCallableTask.get();
                String city = cityNameCallableTask.get();
                String area = areaNameCallableTask.get();
                String addr = address.getAddress();
                detailedAddress = province + city + area + "" + addr;
            } catch (Exception e) {
                logger.error("【行政区域获取出错】获取收货地址列表错误！关键参数：{}", userId);
                e.printStackTrace();
            }
            addressVo.put("detailedAddress", detailedAddress);

            addressVoList.add(addressVo);
        }
        return ResponseUtil.ok(addressVoList);
    }

    /**
     * 收货地址详情
     *
     * @param userId
     * @param id
     * @return
     */
    public Object detail(Integer userId, Integer id) {
        DtsAddress address = addressService.selectById(id, userId);
        if (address == null) {
            return ResponseUtil.fail("收货地址不存在");
        }

        Map<Object, Object> data = new HashMap<Object, Object>();
        data.put("id", address.getId());
        data.put("name", address.getName());
        data.put("provinceId", address.getProvinceId());
        data.put("cityId", address.getCityId());
        data.put("areaId", address.getAreaId());
        data.put("mobile", address.getMobile());
        data.put("address", address.getAddress());
        data.put("isDefault", address.getIsDefault());
        String pname = regionService.findById(address.getProvinceId()).getName();
        data.put("provinceName", pname);
        String cname = regionService.findById(address.getCityId()).getName();
        data.put("cityName", cname);
        String dname = regionService.findById(address.getAreaId()).getName();
        data.put("areaName", dname);
        return ResponseUtil.ok(data);
    }

    /**
     * 校验入参
     *
     * @param address
     * @return
     */
    private Object validate(DtsAddress address) {
        String name = address.getName();
        if (StringUtil.isBlank(name)) {
            return ResponseUtil.badArgument("参数【name】为空");
        }

        // 测试收货手机号码是否正确
        String mobile = address.getMobile();
        if (StringUtil.isBlank(mobile)) {
            return ResponseUtil.badArgument("参数【mobile】为空");
        }
        if (!RegexUtils.isMobileExact(mobile)) {
            return ResponseUtil.badArgument("参数【mobile】错误");
        }

        Integer pid = address.getProvinceId();
        if (pid == null) {
            return ResponseUtil.badArgument("参数【pid】为空");
        }
        if (regionService.findById(pid) == null) {
            return ResponseUtil.badArgument("参数【pid】错误");
        }

        Integer cid = address.getCityId();
        if (cid == null) {
            return ResponseUtil.badArgument("参数【cid】为空");
        }
        if (regionService.findById(cid) == null) {
            return ResponseUtil.badArgument("参数【cid】错误");
        }

        Integer aid = address.getAreaId();
        if (aid == null) {
            return ResponseUtil.badArgument("参数【aid】为空");
        }
        if (regionService.findById(aid) == null) {
            return ResponseUtil.badArgument("参数【aid】错误");
        }

        String detailedAddress = address.getAddress();
        if (StringUtil.isBlank(detailedAddress)) {
            return ResponseUtil.badArgument("参数【address】为空");
        }

        Boolean isDefault = address.getIsDefault();
        if (isDefault == null) {
            return ResponseUtil.badArgument("参数【isDefault】为空");
        }
        return null;
    }

    /**
     * 添加或更新收货地址
     *
     * @param userId
     * @param address
     * @return
     */
    public Object saveOrUpd(Integer userId, DtsAddress address) {
        Integer addressId=address.getId();
        Object error = validate(address);
        if (error != null) {
            return error;
        }
        if (null != address.getId()) {
            DtsAddress oldAddress = addressService.selectById(address.getId(), userId);
            if (oldAddress == null) {
                return ResponseUtil.fail("收货地址不存在");
            }
        }

        if (address.getIsDefault()) {// 如果设置本次地址为默认地址，则需要重置其他收货地址的默认选项
            addressService.resetDefault(userId);
        }

        if (address.getId() == null || address.getId().equals(0)) {
            boolean haveDefault = addressService.haveDefault(userId);
            address.setId(null);
            address.setUserId(userId);
            //没有默认地址，就设置当前为默认地址
            if (!haveDefault) {
                address.setIsDefault(true);
            }
            addressService.add(address);
        } else { // 更新地址
            address.setUserId(userId);
            if (addressService.update(address) == 0) {
                return ResponseUtil.updatedDataFailed();
            }
        }
        return ResponseUtil.ok(addressId == null ? "新增成功" : "修改成功", address.getId());
    }


    /**
     * 删除收货地址
     *
     * @param userId
     * @param id
     * @return
     */
    public Object delete(Integer userId, Integer id) {
        if (id == null) {
            return ResponseUtil.badArgument("参数【id】为空");
        }
        DtsAddress address = addressService.selectById(id, userId);
        if (address == null) {
            return ResponseUtil.fail("收货地址不存在");
        }
        addressService.delete(id, userId);
        return ResponseUtil.ok();
    }
}
